home *** CD-ROM | disk | FTP | other *** search
/ One Click 14 / OneClick14.iso / Ferramentas / Convert XLS to Pdf / xls2pdf_setup.exe / {app} / lib / pdf_main.ps < prev    next >
Encoding:
Text File  |  2002-11-06  |  29.5 KB  |  939 lines

  1. %    Copyright (C) 1994, 2000 Aladdin Enterprises.  All rights reserved.
  2. % This software is provided AS-IS with no warranty, either express or
  3. % implied.
  4. % This software is distributed under license and may not be copied,
  5. % modified or distributed except as expressly authorized under the terms
  6. % of the license contained in the file LICENSE in this distribution.
  7. % For more information about licensing, please refer to
  8. % http://www.ghostscript.com/licensing/. For information on
  9. % commercial licensing, go to http://www.artifex.com/licensing/ or
  10. % contact Artifex Software, Inc., 101 Lucas Valley Road #110,
  11. % San Rafael, CA  94903, U.S.A., +1(415)492-9861.
  12.  
  13. % $Id: pdf_main.ps,v 1.63 2002/11/05 20:56:02 ghostgum Exp $
  14. % pdf_main.ps
  15. % PDF file- and page-level operations.
  16.  
  17. /.setlanguagelevel where { pop 2 .setlanguagelevel } if
  18. .currentglobal true .setglobal
  19. /pdfdict where { pop } { /pdfdict 100 dict def } ifelse
  20. pdfdict begin
  21.  
  22. % Patch in an obsolete variable used by some third-party software.
  23. /#? false def
  24.  
  25. % Test whether the current output device handles pdfmark.
  26. /.writepdfmarkdict 1 dict dup /pdfmark null put readonly def
  27. /.writepdfmarks {    % - .writepdfmarks <bool>
  28.   currentdevice //.writepdfmarkdict .getdeviceparams
  29.   mark eq { false } { pop pop true } ifelse
  30.   systemdict /DOPDFMARKS known or 
  31. } bind def
  32.  
  33. % For simplicity, we use a single interpretation dictionary for all
  34. % PDF graphics execution, even though this is too liberal.
  35. /pdfopdict mark
  36.   objopdict { } forall
  37.   drawopdict { } forall
  38.   /endstream { exit } bind
  39.   (%%EOF) cvn { exit } bind        % for filters
  40.     % PDF 1.1 operators
  41.   /BX { /BXlevel BXlevel 1 add store } bind
  42.   /EX { /BXlevel BXlevel 1 sub store } bind
  43.   /PS { cvx exec } bind
  44.     % PDF 1.2 operators
  45.   /BMC { pop } bind
  46.   /BDC { pop pop } bind
  47.   /EMC { }
  48.   /MP { pop } bind
  49.   /DP { pop pop } bind
  50. .dicttomark readonly def
  51.  
  52. % ======================== Main program ======================== %
  53.  
  54. end            % pdfdict
  55. userdict begin
  56.  
  57. /defaultfontname /Times-Roman def
  58.  
  59. % Make sure the registered encodings are loaded, so we don't run the risk
  60. % that some of the indices for their names will overflow the packed
  61. % representation.  (Yes, this is a hack.)
  62. SymbolEncoding pop
  63. DingbatsEncoding pop
  64.  
  65. % Redefine 'run' so it recognizes PDF files.
  66. systemdict begin
  67. /.runps /run load def
  68. /runpdfstring 5 string def
  69. /run {
  70.   dup type /filetype ne { (r) file } if
  71.   dup ( ) .peekstring {
  72.     (%) eq {
  73.       dup (  ) .peekstring {
  74.     (%P) eq {
  75.       dup //runpdfstring {
  76.         % Some invalid files might have extra-long first lines....
  77.         { readstring } .internalstopped not { pop pop exit } if
  78.         pop =string
  79.       } loop
  80.       //runpdfstring (%PDF-) anchorsearch {
  81.         pop pop 
  82.         dup (%stdin) (r) file eq {
  83.           % Copy PDF from stdin to temporary file then run it.
  84.           null (w+) //systemdict /.tempfile get exec exch 3 1 roll
  85.           % stack: tempname stdin tempfile
  86.           dup //runpdfstring writestring
  87.           1024 string
  88.           {
  89.         % stack: tempname stdin tempfile string
  90.         2 index 1 index readstring
  91.         exch 3 index exch writestring
  92.         not { exit } if
  93.           }
  94.           loop
  95.           pop exch closefile
  96.           % stack: tempname tempfile
  97.           dup 0 setfileposition
  98.           dup runpdf
  99.           closefile deletefile
  100.         } {
  101.           runpdf
  102.         } ifelse
  103.       } {
  104.         pop cvx .runexec
  105.       } ifelse
  106.     } {
  107.       cvx .runps
  108.     } ifelse
  109.       } {
  110.     closefile
  111.       } ifelse
  112.     } {
  113.       cvx .runps
  114.     } ifelse
  115.   } {
  116.     closefile
  117.   } ifelse
  118. } bind odef
  119. currentdict /runpdfstring .undef
  120.  
  121. /runpdf {        % <file> runpdf -
  122.    userdict begin
  123.     % It turns out that the PDF interpreter uses memory more
  124.     % effectively if it is run under at least one level of save.
  125.     % This is counter-intuitive, and we don't understand why it happens,
  126.     % but the improvement is significant.
  127.    /PDFTopSave save def
  128.    0 setobjectformat
  129.    /Page# null def
  130.    /Page null def
  131.    /DSCPageCount 0 def
  132.    /PDFSave null def
  133.    GS_PDF_ProcSet begin
  134.    pdfdict begin
  135.    pdfopen begin
  136.    Trailer /Root oget /Pages oget /CropBox knownoget
  137.     { mark /CropBox 3 -1 roll /PAGES pdfmark
  138.     }
  139.    if
  140.    /FirstPage where 
  141.     { pop FirstPage dup pdfpagecount gt
  142.       { (\nRequested FirstPage is greater than the number of pages in the file: ) print
  143.         pdfpagecount = flush
  144.       } if
  145.     } {
  146.       1
  147.     } ifelse
  148.    1
  149.    /LastPage where { pop LastPage pdfpagecount .min } { pdfpagecount } ifelse
  150.    2 index 1 index gt
  151.     { (   No pages will be processed \(FirstPage > LastPage\).) = flush }
  152.     { QUIET not
  153.       { (Processing pages ) print 2 index =only ( through ) print dup =only
  154.         (.) = flush
  155.       }
  156.      if
  157.     }
  158.    ifelse
  159.     { dup /Page# exch store
  160.       QUIET not { (Page ) print dup == flush } if
  161.       pdfgetpage pdfshowpage
  162.     } for
  163.    Repaired { printrepaired } if
  164.    currentdict pdfclose
  165.    end            % temporary dict
  166.    end            % pdfdict
  167.    end            % GS_PDF_ProcSet
  168.    PDFTopSave restore
  169.    end            % userdict
  170. } bind def
  171. end            % systemdict
  172. % Redefine the procedure that the C code uses for running piped input.
  173. % It is OK to use { (%stdin) run } here, because a startjob cannot occur.
  174. /.runstdin {
  175.   { (%stdin) run } execute0
  176. } bind def
  177.  
  178. end            % userdict
  179. pdfdict begin
  180.  
  181. % ======================== File parsing ======================== %
  182.  
  183. % Read the cross-reference and trailer sections.
  184.  
  185. /traileropdict mark
  186.   (<<) cvn { mark } bind
  187.   (>>) cvn { { .dicttomark } stopped {
  188.           (   **** File has unbalanced >> in trailer.\n) pdfformaterror
  189.              } if } bind
  190.   ([) cvn { mark } bind        % ditto
  191.   (]) cvn dup load
  192. %  /true true        % see .pdfexectoken in pdf_base.ps
  193. %  /false false        % ibid.
  194. %  /null null        % ibid.
  195.   /R { /resolveR cvx 3 packedarray cvx } bind    % see Objects below
  196.   /startxref /exit load
  197. .dicttomark readonly def
  198.  
  199. % Because of EOL conversion, lines with fixed contents might be followed
  200. % by one or more blanks.
  201. /lineeq            % <filestr> <conststr> lineeq <bool>
  202.  { anchorsearch
  203.     { pop { ( ) anchorsearch not { () eq exit } if pop } loop }
  204.     { pop false }
  205.    ifelse
  206.  } bind def
  207. /linene { lineeq not } bind def
  208.  
  209. % Read (mostly scan) the cross-reference table.
  210. /readxref        % <pos> readxref <trailerdict>
  211.  { PDFoffset add PDFfile exch setfileposition
  212.         % In some PDF files, this position actually points to
  213.         % white space before the xref line.  Skip over this here.
  214.    { PDFfile fileposition PDFfile read pop 32 gt { exit } if pop
  215.    } loop
  216.    PDFfile exch setfileposition
  217.         % The PDF specification says that the 'xref' must be on a line
  218.         % by itself. The code here formerly used readline and linene to
  219.         % check this. However, Acrobat Reader only requires the line to
  220.         % begin with 'xref', and there are enough applications producing
  221.         % non-compliant PDF files that we have to do this too.
  222.    PDFfile pdfstring 0 4 getinterval readstring pop
  223.    (xref) ne { /readxref cvx /syntaxerror signalerror } if
  224.         % Store the xref table entry position for each object.
  225.         % We only need to read the run headers, not every entry.
  226.     { PDFfile token pop        % first object # or trailer
  227.       dup /trailer eq { pop exit } if
  228.       PDFfile pdfstring readline pop
  229.       token pop            % entry count
  230.       exch pop exch
  231.         % This section might be adding new objects:
  232.         % ensure that Objects and Generations are big enough.
  233.         % Stack: count obj#
  234.       2 copy add growPDFobjects
  235.       PDFfile fileposition 3 -1 roll
  236.        { Objects 2 index lget null eq    % later update might have set it
  237.       { Objects 2 index 2 index cvx lput }
  238.          if exch 1 add exch 20 add
  239.        }
  240.       repeat PDFfile exch setfileposition pop
  241.     } loop
  242.    count /pdfemptycount exch def
  243.    PDFfile traileropdict .pdfrun
  244.  } bind def
  245.  
  246. % Open a PDF file and read the header, trailer, and cross-reference.
  247. /pdfopen {        % <file> pdfopen <dict>
  248.     % Color space substitution in PDF is handled somewhat differently
  249.     % than in PostScript. A given device color space will be substituted
  250.     % if the corresponding "Default..." entry exists in the Page's
  251.     % Resource dictionary (which might be inhereted); there is no
  252.     % UseCIEColor to enable/disable color mapping.
  253.     %
  254.     % This behavior is achieved by always setting UseCIEColor to true
  255.     % in the page device dictionary. If the value of this parameter was
  256.     % originally false (i.e.: the output device does not perform color
  257.     % space substitution by default), the instances DefaultGray,
  258.     % DefaultRGB, and DefaultCMYK of the (local) ColorSpace category
  259.     % are redefined to be DeviceGray, DeviceRGB, and DeviceCMYK,
  260.     % respectively. This is not done if UseCIEColor is true by default,
  261.     % as in that case color substitution is presumably desired even
  262.     % if the file does not request it.
  263.    currentpagedevice /UseCIEColor .knownget dup { pop } if not
  264.     { .currentglobal false .setglobal
  265.       /DefaultGray { /DeviceGray } cvlit /ColorSpace defineresource pop
  266.       /DefaultRGB { /DeviceRGB } cvlit /ColorSpace defineresource pop
  267.       /DefaultCMYK { /DeviceCMYK } cvlit /ColorSpace defineresource pop
  268.       .setglobal
  269.     }
  270.    if
  271.   pdfopenfile begin
  272.   pdfopencache
  273.   .writepdfmarks {
  274.     % Copy bookmarks (outline) to the output.
  275.     Trailer /Root oget /Outlines knownoget {
  276.       /First knownoget {
  277.     { dup writeoutline /Next knownoget not { exit } if } loop
  278.       } if
  279.     } if
  280.   } if        % end .writepdfmarks
  281.   currentdict end
  282. } bind def
  283. /pdfopencache {        % - pdfopencache -
  284.     % Create and initialize some caches.
  285.   /PageCount pdfpagecount def
  286.   /PageNumbers PageCount 65534 .min dict def
  287.   /PageIndex PageCount 65534 .min array def
  288. } bind def
  289. /pdfopenfile {        % <file> pdfopenfile <dict>
  290.    pdfdict readonly pop        % can't do it any earlier than this
  291.    15 dict begin
  292.    /LocalResources 0 dict def
  293.    /DefaultMatrix null def    % establish binding
  294.    /Printed where { pop } {
  295.         % Guess whether the output device is a printer.
  296.      /Printed currentpagedevice /OutputFile known def
  297.    } ifelse
  298.    /PSLevel1 where { pop } { /PSLevel1 false def } ifelse
  299.    % NB: PDFfile is used outside of the PDF code to determine that a
  300.    % PDF job is being processed; to not change or hide this key.
  301.    cvlit /PDFfile exch def
  302.    /PDFsource PDFfile def
  303.    /Repaired false def
  304.    PDFfile dup 0 setfileposition pdfstring readstring 
  305.    not {/pdfopen cvx /syntaxerror signalerror} if
  306.    (%PDF-) search not {/pdfopen cvx /syntaxerror signalerror} if
  307.    length /PDFoffset exch def pop cvr /PDFversion exch def
  308.    findxref
  309.    initPDFobjects
  310.     % Read the last cross-reference table.
  311.    readxref /Trailer exch def
  312.    Trailer /Encrypt known
  313.     { pdf_process_Encrypt    % signal error
  314.     }
  315.    if
  316.     % Read any previous cross-reference tables.
  317.    Trailer { /Prev knownoget not { exit } if readxref } loop
  318.    currentdict end
  319.  } bind def
  320.  
  321. % Skip backward over the %%EOF at the end of the PDF file, and read
  322. % the preceding startxref line.  The PDF specification unambiguously
  323. % requires that the %%EOF appear on a line by itself, and that the
  324. % startxref and the following position value appear on separate lines;
  325. % however, some applications (including, apparently, Acrobat Distiller
  326. % on the Macintosh) may add up to 2K of garbage after the %%EOF, and some
  327. % other applications also truncate the %%EOF to %%EO, and/or put the
  328. % startxref and the following value on the same line.
  329. % A file reported from Distiller 3.02b for AIX 4.1.1 has 2076 bytes
  330. % of garbage. The tolerance is increased to 4K to cover future
  331. % applications and bigger allocation units.
  332. /findxref {        % - findxref <xrefpos>
  333.   PDFfile dup dup 0 setfileposition bytesavailable
  334.   dup /PDFfilelen exch def
  335.     % Find the last %%EOF string (within 4096 bytes)
  336.   4096 sub PDFoffset .max
  337.   2 copy setfileposition
  338.   PDFfilelen exch sub string 1 index exch readstring pop {
  339.     (\015%%EO) search {        % Adobe can handle truncated key string
  340.       pop pop            % if found, keep searching 'post' string
  341.     } {
  342.       (\012%%EO) search
  343.     { pop pop } { exit } ifelse    % exit if neither string found
  344.     } ifelse
  345.   } loop
  346.   PDFfilelen exch length sub 4 sub PDFoffset .max exch 1 index setfileposition
  347.     % Stack: eofpos
  348.     % Check for whether this is, in fact, a valid PDF file.
  349.   dup PDFfilelen exch sub dup dup 7 gt exch 6 lt or {
  350.     pop true
  351.   } {
  352.     string PDFfile exch readstring pop
  353.     dup (%%EOF\n) eq exch dup (%%EOF\r) eq
  354.     exch (%%EOF\r\n) eq or or not
  355.   } ifelse {
  356.     (   **** Warning: File has a corrupted %%EOF marker, or garbage after %%EOF.\n)
  357.     pdfformaterror
  358.   } if
  359.   PDFfile exch setfileposition
  360.     % Now read the startxref and xref start position.
  361.   prevline token not { null } if dup type /integertype eq {
  362.     exch pop cvi        % xref start position
  363.     exch PDFfile exch setfileposition
  364.     prevline (startxref) linene { /findxref cvx /syntaxerror signalerror } if
  365.     pop
  366.   } {    % else, this file has 'startxref #####' format
  367.     (startxref) ne { /findxref cvx /syntaxerror signalerror } if
  368.     cvi        % xref start position
  369.     (   **** Warning: format of the startxref line in this file is invalid.\n)
  370.     pdfformaterror
  371.     exch PDFfile exch setfileposition
  372.   } ifelse
  373. } bind def
  374. /stderrfile (%stderr) (w) file def
  375. /stderrprint {                % <string> stderrprint -
  376.   //stderrfile dup 3 -1 roll writestring flushfile
  377. } bind def
  378. /pdfformaterror {    % <string> pdfformaterror -
  379.   stderrprint
  380.   /Repaired true store
  381. } bind def
  382.  
  383. /knownoget_safe
  384. { knownoget
  385. } odef
  386.  
  387. /printProducer {
  388.   Trailer /Info { knownoget_safe } stopped { false } if {
  389.     /Producer knownoget not { null } if
  390.   } {
  391.     null
  392.   } ifelse
  393.   dup null eq {
  394.     pop
  395.   } {
  396.     (   **** The file was produced by: \n   **** >>>> ) stderrprint
  397.     % Handle a Unicode Producer.
  398.     (\376\377) anchorsearch {
  399.       pop dup length 2 idiv string 0 1 2 index length 1 sub {
  400.         % Stack: origstr newstr i
  401.     1 index exch 3 index 1 index 2 mul 1 add get put
  402.       } for exch pop
  403.     } if
  404.     stderrprint
  405.     ( <<<<\n) stderrprint
  406.   } ifelse
  407. } bind def
  408. /printrepaired {
  409.    (\n   **** This file had errors that were repaired or ignored.\n)
  410.   stderrprint
  411.   printProducer
  412.   (   **** Please notify the author of the software that produced this\n)
  413.   stderrprint
  414.   (   **** file that it does not conform to Adobe's published PDF\n)
  415.   stderrprint
  416.   (   **** specification.\n\n)
  417.   stderrprint
  418. } bind def
  419.  
  420. % Write the outline structure for a file.  Uses linkdest (below).
  421. /writeoutline        % <outlinedict> writeoutline -
  422.  { mark
  423.    0 2 index /First knownoget
  424.     { { exch 1 add exch /Next knownoget not { exit } if } loop }
  425.    if
  426.         % stack: dict mark count
  427.    dup 0 eq
  428.     { pop 1 index
  429.     }
  430.     { 2 index /Count knownoget { 0 lt { neg } if } if
  431.       /Count exch 3 index
  432.     }
  433.    ifelse linkdest /Title oget /Title exch /OUT pdfmark
  434.    /First knownoget
  435.     { { dup writeoutline /Next knownoget not { exit } if } loop }
  436.    if
  437.  } bind def
  438.  
  439. % Close a PDF file.
  440. /pdfclose        % <dict> pdfclose -
  441.  { begin
  442.    PDFfile closefile
  443.    end
  444.  } bind def
  445.  
  446. % ======================== Page accessing ======================== %
  447.  
  448. % Get a (possibly inherited) attribute of a page.
  449. /pget            % <pagedict> <key> pget <value> -true-
  450.             % <pagedict> <key> pget -false-
  451.  { 2 copy knownoget
  452.     { exch pop exch pop true
  453.     }
  454.     { exch /Parent knownoget
  455.        { exch pget }
  456.        { pop false }
  457.       ifelse
  458.     }
  459.    ifelse
  460.  } bind def
  461.  
  462. % Get the value of a resource on a given page.
  463. /rget {            % <resname> <pagedict> <restype> rget <value> -true-
  464.             % <resname> <pagedict> <restype> rget -false-
  465.   LocalResources 1 index knownoget {
  466.      3 index knownoget
  467.   } {
  468.     false
  469.   } ifelse {
  470.     exch pop exch pop exch pop true
  471.   } {
  472.     exch /Resources pget {
  473.       exch knownoget { exch knownoget } { pop false } ifelse
  474.     } {
  475.       pop pop false
  476.     } ifelse
  477.   } ifelse
  478. } bind def
  479.  
  480. % Get the total number of pages in the document.
  481. /pdfpagecount        % - pdfpagecount <int>
  482.  { Trailer /Root oget /Pages oget /Count oget
  483.  } bind def
  484.  
  485. % Find the N'th page of the document by iterating through the Pages tree.
  486. % The first page is numbered 1.
  487. /pdffindpageref {        % <int> pdffindpage <objref>
  488.   dup Trailer /Root oget /Pages get
  489.     {        % We should be able to tell when we reach a leaf
  490.         % by finding a Type unequal to /Pages.  Unfortunately,
  491.         % some files distributed by Adobe lack the Type key
  492.         % in some of the Pages nodes!  Instead, we check for Kids.
  493.       dup oforce /Kids knownoget not { exit } if
  494.       exch pop null
  495.       0 1 3 index length 1 sub {
  496.          2 index exch get
  497.      dup oforce dup /Kids known { /Count oget } { pop 1 } ifelse
  498.         % Stack: index kids null noderef count
  499.      dup 5 index ge { pop exch pop exit } if
  500.      5 -1 roll exch sub 4 1 roll pop
  501.       } for exch pop
  502.         % Stack: index null|noderef
  503.       dup null eq { pop pop 1 null exit } if
  504.     } loop
  505.         % Stack: index countleft noderef
  506.    1 index 1 ne { pop pop /pdffindpage cvx /rangecheck signalerror } if
  507.    exch pop
  508.    PageIndex 2 index 1 sub 65533 .min 2 index oforce put
  509.    PageNumbers 1 index oforce 3 index dup 65534 le
  510.     { put }
  511.     { pop pop pop }    % don't store more than 65534 pagenumbers
  512.    ifelse
  513.    exch pop
  514. } bind def
  515. /pdffindpage {        % <int> pdffindpage <pagedict>
  516.   pdffindpageref oforce
  517. } bind def
  518.  
  519. % Find the N'th page of the document.
  520. % The first page is numbered 1.
  521. /pdfgetpage        % <int> pdfgetpage <pagedict>
  522.  { PageIndex 1 index 1 sub dup 65533 lt
  523.     { get }
  524.     { pop pop null }
  525.    ifelse
  526.    dup null ne
  527.     { exch pop oforce }
  528.     { pop pdffindpage }
  529.    ifelse
  530.  } bind def
  531.  
  532. % Find the page number of a page object (inverse of pdfgetpage).
  533. /pdfpagenumber        % <pagedict> pdfpagenumber <int>
  534.  {    % We use the simplest and stupidest of all possible algorithms....
  535.    PageNumbers 1 index .knownget
  536.     { exch pop
  537.     }
  538.     { 1 1 PageCount 1 add    % will give a rangecheck if not found
  539.        { dup pdfgetpage oforce 2 index eq { exit } if pop
  540.        }
  541.       for exch pop
  542.     }
  543.    ifelse
  544.  } bind def
  545.  
  546. % Display a given page.
  547. /boxrect        % [<llx> <lly> <urx> <ury>] boxrect <x> <y> <w> <h>
  548.  { aload pop exch 3 index sub exch 2 index sub
  549.  } bind def
  550. /resolvedest {        % <name|string|other> resolvedest <other|null>
  551.   dup type /nametype eq {
  552.     Trailer /Root oget /Dests knownoget {
  553.       exch knownoget not { null } if
  554.     } {
  555.       pop null
  556.     } ifelse
  557.   } {
  558.     dup type /stringtype eq {
  559.       Trailer /Root oget /Names knownoget {
  560.     /Dests knownoget {
  561.       exch nameoget
  562.     } {
  563.       pop null
  564.     } ifelse
  565.       } {
  566.     pop null
  567.       } ifelse
  568.     } if
  569.   } ifelse
  570. } bind def
  571. /linkdest {        % <link|outline> linkdest
  572.             %   ([/Page <n>] /View <view> | ) <link|outline>
  573.   dup /Dest knownoget
  574.     { resolvedest
  575.       dup type /dicttype eq { /D knownoget not { null } if } if
  576.       dup null eq
  577.        { pop }
  578.        { dup 0 oget
  579.      dup null eq
  580.       { pop }
  581.       { dup type /integertype ne { pdfpagenumber } if
  582.         /Page exch 4 -2 roll
  583.       }
  584.      ifelse
  585.      dup length 1 sub 1 exch getinterval /View exch 3 -1 roll
  586.        }
  587.       ifelse
  588.     }
  589.    if
  590. } bind def
  591. % <pagedict> mark ... -proc- -
  592. /namedactions 8 dict dup begin
  593.   /FirstPage {
  594.     /Page 1 3 -1 roll
  595.   } def
  596.   /LastPage {
  597.     counttomark 2 add index pdfpagecount /Page exch 3 -1 roll
  598.   } def
  599.   /NextPage {
  600.     counttomark 2 add index pdfpagenumber 1 add /Page exch 3 -1 roll
  601.   } def
  602.   /PrevPage {
  603.     counttomark 2 add index pdfpagenumber 1 sub /Page exch 3 -1 roll
  604.   } def
  605. end readonly def
  606. % <pagedict> <annotdict> -proc- -
  607. /annottypes 5 dict dup begin
  608.   /Text {
  609.     mark exch
  610.      { /Rect /Open /Contents }
  611.      { 2 copy knownoget { 3 -1 roll } { pop } ifelse }
  612.     forall pop /ANN pdfmark
  613.   } bind def
  614.   /Link {
  615.     mark exch
  616.     dup /C knownoget { /Color exch 3 -1 roll } if
  617.      { /Rect /Border }
  618.      { 2 copy knownoget { 3 -1 roll } { pop } ifelse }
  619.     forall dup /A knownoget {
  620.       dup /URI known {
  621.         /A mark 3 2 roll    % <<>> /A [ <<action>>
  622.         { oforce } forall
  623.         .dicttomark
  624.         3 2 roll
  625.       } {
  626.         dup /D knownoget {
  627.       exch pop exch dup length dict copy dup /Dest 4 -1 roll put
  628.         } {
  629.       /N knownoget {        % Assume /S /Named
  630.          namedactions exch .knownget { exec } if
  631.       } if
  632.         } ifelse
  633.       } ifelse
  634.     } if
  635.     linkdest pop /LNK pdfmark
  636.   } bind def
  637. end readonly def
  638.  
  639. % **** The following procedure should not be changed to allow clients
  640. % **** to directly interface with the constituent procedures. GSview
  641. % **** and some Artifex customers rely on the pdfshowpage_init,
  642. % **** pdfshowpage_setpage, pdfshowpage_finish so all logic should be
  643. % **** implemented in one of those three procedures.
  644. /pdfshowpage        % <pagedict> pdfshowpage -
  645.  { dup /Page exch store
  646.    pdfshowpage_init 
  647.    pdfshowpage_setpage 
  648.    pdfshowpage_finish
  649.  } bind def
  650.  
  651. /pdfpagecontents    % <pagedict> pdfpagecontents <contents>
  652.  { } bind def
  653.  
  654. /pdfshowpage_init     % <pagedict> pdfshowpage_init <pagedict>
  655.  { /DSCPageCount DSCPageCount 1 add store
  656.  } bind def
  657.  
  658. /.pdfshowpage_Install {    % <pagedict> [<prevproc>] .pdfshowpage_Install -
  659.   exch
  660.     % We would like to clip to the CropBox here, but the subsequent
  661.     % initgraphics would override it.  Instead, we have to handle it
  662.     % in graphicsbeginpage.
  663.   dup /CropBox pget dup {exch pop} if systemdict /UseCropBox known and {
  664.     dup /CropBox pget pop dup 0 get neg exch 1 get neg translate
  665.   } {
  666.     dup /MediaBox pget {
  667.       dup 0 get neg exch 1 get neg translate
  668.     } if
  669.   } ifelse
  670.   pop 0 get exec
  671. } bind def
  672.  
  673. /pdfshowpage_setpage {    % <pagedict> pdfshowpage_setpage <pagedict>
  674.   5 dict begin        % for setpagedevice
  675.     % Stack: pagedict
  676.   % UseCIEColor is always true for PDF; see the comment in runpdf above
  677.   /UseCIEColor true def
  678.   currentpagedevice /Orientation 2 index /Rotate pget not { 0 } if 90 idiv
  679.     % Rotate specifies *clockwise* rotation!
  680.     neg 3 and def
  681.     % Stack: pagedict currentpagedict
  682.   1 index /CropBox pget dup {exch pop} if systemdict /UseCropBox known and {
  683.             % Set the page size.
  684.     1 index /CropBox pget pop
  685.     boxrect 2 array astore /PageSize exch def pop pop
  686.   } {
  687.     1 index /MediaBox pget {
  688.             % Set the page size.
  689.       boxrect 2 array astore /PageSize exch def pop pop
  690.     } if
  691.   } ifelse
  692.   dup /Install .knownget {
  693.             % Don't let the Install procedure get more deeply
  694.             % nested after every page.
  695.       dup type dup /arraytype eq exch /packedarraytype eq or {
  696.     dup length 4 eq {
  697.       dup 2 get /.pdfshowpage_Install load eq {
  698.         1 get 0 get    % previous procedure
  699.       } if
  700.     } if
  701.       } if
  702.   } {
  703.     { }
  704.   } ifelse 1 array astore
  705.   2 index exch /.pdfshowpage_Install load /exec load
  706.   4 packedarray cvx
  707.     % Stack: pagedict currentpagedict installproc
  708.   /Install exch def
  709.     % Stack: pagedict currentpagedict
  710.   pop currentdict end setpagedevice
  711. } bind def
  712.  
  713. /pdfshowpage_finish {    % <pagedict> pdfshowpage_finish -
  714.    save /PDFSave exch store
  715.    /PDFdictstackcount countdictstack store
  716.    (before exec) VMDEBUG
  717.  
  718.    % set up color space substitution (this must be inside the page save)
  719.    pdfshowpage_setcspacesub
  720.  
  721.   .writepdfmarks {
  722.  
  723.     % Copy the crop box.
  724.     dup /CropBox knownoget {
  725.     % If the page has been rotated, rotate the CropBox.
  726.       mark /CropBox 3 -1 roll
  727.       3 index /Rotate pget {
  728.     90 idiv 1 and 0 ne {
  729.       aload pop 4 -2 roll exch 4 2 roll exch 4 array astore
  730.     } if
  731.       } if
  732.       /PAGE pdfmark
  733.     } if
  734.  
  735.     % Copy annotations and links.
  736.     dup /Annots knownoget {
  737.       0 1 2 index length 1 sub
  738.        { 1 index exch oget
  739.          dup /Subtype oget annottypes exch .knownget { exec } { pop } ifelse
  740.        }
  741.       for pop
  742.     } if
  743.  
  744.   } if        % end .writepdfmarks
  745.  
  746.     % Display the actual page contents.
  747.    6 dict begin
  748.    /BXlevel 0 def
  749.    /BGDefault currentblackgeneration def
  750.    /UCRDefault currentundercolorremoval def
  751.     %****** DOESN'T HANDLE COLOR TRANSFER YET ******
  752.    /TRDefault currenttransfer def
  753.   matrix currentmatrix 2 dict
  754.   2 index /CropBox knownoget {
  755.     boxrect 4 array astore 1 index /ClipRect 3 -1 roll put
  756.   } if
  757.   dictbeginpage /DefaultMatrix 1 index store setmatrix
  758.   dup          % for showing annotations below
  759.   count 1 sub /pdfemptycount exch store
  760.     % If the page uses any transparency features, show it within
  761.     % a transparency group.
  762.   PDFversion 1.4 lt NOTRANSPARENCY or {
  763.     showpagecontents
  764.   } {
  765.     dup pageusestransparency {
  766.       % Show the page within a PDF 1.4 device filter.
  767.       0 .pushpdf14devicefilter {
  768.     % If the page has a Group, enclose contents in transparency group.
  769.         % (Adobe Tech Note 5407, sec 9.2)
  770.         dup /Group knownoget {
  771.       1 index /CropBox knownoget not {
  772.         1 index /MediaBox oget
  773.       } if .beginformgroup {
  774.         showpagecontents
  775.       } .internalstopped {
  776.         .discardtransparencygroup stop
  777.       } if .endtransparencygroup
  778.         } {
  779.       showpagecontents
  780.         } ifelse
  781.       } .internalstopped {
  782.     % todo: discard
  783.     .popdevicefilter stop
  784.       } if .popdevicefilter
  785.     } {
  786.       showpagecontents
  787.     } ifelse
  788.   } ifelse
  789.   % check for extra garbage on the ostack and clean it up
  790.   count pdfemptycount sub dup 0 ne {
  791.     (   **** File did not complete the page properly and may be damaged.\n)
  792.     pdfformaterror
  793.     { pop } repeat
  794.   } {
  795.     pop
  796.   } ifelse
  797.   % todo: mixing drawing ops outside the device filter could cause
  798.   % problems, for example with the pnga device.
  799.   /Annots knownoget { { oforce drawannot } forall } if
  800.   endpage
  801.   end            % scratch dict
  802.   % Some PDF files don't have matching q/Q (gsave/grestore) so we need
  803.   % to clean up any left over dicts from the dictstack
  804.   countdictstack PDFdictstackcount sub dup 0 ne { 
  805.     (   **** Warning: File has imbalanced q/Q operators \(too many q's\)\n)
  806.     pdfformaterror
  807.     { end } repeat
  808.   } {
  809.     pop
  810.   } ifelse
  811.   (after exec) VMDEBUG
  812.   Repaired        % pass Repaired state around the restore
  813.   PDFSave restore
  814.   /Repaired exch def
  815. } bind def
  816. /showpagecontents {    % <pagedict> showpagecontents -
  817.   gsave        % preserve gstate for Annotations later
  818.   /Contents knownoget not { 0 array } if
  819.   dup type /arraytype ne { 1 array astore } if {
  820.     oforce false resolvestream pdfopdict .pdfrun
  821.   } forall
  822.   grestore
  823. } bind def
  824. /processcolorspace {    % - processcolorspace <colorspace>
  825.     % The following is per the PLRM3.
  826.   currentdevice 1 dict dup /ProcessColorModel dup put .getdeviceparams
  827.   exch pop exch pop
  828.   dup type /nametype ne { cvn } if
  829.   dup { setcolorspace } .internalstopped { pop /DeviceRGB } if
  830. } bind def
  831.  
  832. % ------ Transparency support ------ %
  833.  
  834. % Determine whether a page might invoke any transparency features:
  835. %    - Non-default BM, ca, CA, or SMask in an ExtGState
  836. %    - Image XObject with SMask
  837. % Note: we deliberately don't check to see whether a Group is defined,
  838. % because Adobe Illustrator 10 (and possibly other applications) define
  839. % a page-level group whether transparency is actually used or not.
  840. % Ignoring the presence of Group is justified because, in the absence
  841. % of any other transparency features, they have no effect.
  842. /pageusestransparency {        % <pagedict> pageusestransparency <bool>
  843.   PDFversion 1.4 lt NOTRANSPARENCY or {
  844.     pop false
  845.   } {
  846.     false exch {
  847.       dup resourceusestransparency { pop not exit } if
  848.       /Parent knownoget not { exit } if
  849.     } loop
  850.   } ifelse
  851. } bind def
  852. % Check the Resources of a page or Form.
  853. /resourceusestransparency {    % <dict> resourceusestransparency <bool>
  854.   {    % Use loop to provide an exitable context.
  855.     /Resources knownoget not { 0 dict } if
  856.     dup /ExtGState knownoget {
  857.       false exch {
  858.     exch pop oforce
  859.     dup /BM knownoget { dup /Normal ne exch /Compatible ne and
  860.                         { pop not exit } if
  861.                           } if
  862.     dup /ca knownoget { 1 ne { pop not exit } if } if
  863.     dup /CA knownoget { 1 ne { pop not exit } if } if
  864.     dup /SMask knownoget { /None ne { pop not exit } if } if
  865.     pop
  866.       } forall { pop true exit } if
  867.     } if
  868.     dup /XObject knownoget {
  869.       false exch {
  870.     exch pop oforce dup /Subtype get
  871.     dup /Image eq { 1 index /SMask known { pop pop not exit } if } if
  872.     /Form eq {
  873.       resourceusestransparency { not exit } if
  874.     } {
  875.       pop
  876.     } ifelse
  877.       } forall { pop true exit } if
  878.     } if
  879.     pop false exit
  880.   } loop
  881. } bind def
  882.  
  883. % ------ ColorSpace substitution support ------ %
  884.  
  885. %
  886. %  <pagedict>   pdfshowpage_setcspacesub   <pagedict>
  887. %
  888. % Set up color space substitution for a page. Invocations of this procedure
  889. % must be bracketed by the save/restore operation for the page, to avoid
  890. % unintended affects on other pages.
  891. %
  892. % If any color space substitution is used, and the current color space is a
  893. % device dependent color space, make sure the current color space is updated.
  894. % There is an optimization in the setcolorspace pseudo-operator that does
  895. % nothing if both the current and operand color spaces are the same. For
  896. % PostScript this optimization is disabled if the UseCIEColor page device
  897. % parameter is true. This is not the case for PDF, as performance suffers
  898. % significantly on some PDF files if color spaces are set repeatedly. Hence,
  899. % if color space substitution is to be used, and the current color space
  900. % is a device dependent color space, we must make sure to "transition" the
  901. % current color space.
  902. %
  903. /pdfshowpage_setcspacesub
  904.   {
  905.     false
  906.       { /DefaultGray /DefaultRGB /DefaultCMYK }
  907.       {
  908.         dup 3 index /ColorSpace //rget exec
  909.           { resolvecolorspace /ColorSpace defineresource pop }
  910.           { pop }
  911.         ifelse
  912.       }
  913.     forall
  914.  
  915.     % if using color space substitution, "transition" the current color space
  916.       {
  917.         currentcolorspace dup length 1 eq   % always an array
  918.           {
  919.             0 get
  920.             dup /DeviceGray eq 1 index /DeviceRGB eq or 1 index /DeviceCMYK or
  921.               { /Pattern setcolorspace setcolorspace }
  922.               { pop }
  923.             ifelse
  924.           }
  925.           { pop }
  926.         if
  927.       }
  928.     if
  929.   }
  930. bind def
  931.  
  932.  
  933.  
  934. end            % pdfdict
  935. .setglobal
  936.